package com.yoona.system.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yoona.common.constants.WeChatConstants;
import com.yoona.common.enums.CommonEnums;
import com.yoona.common.response.BaseResponse;
import com.yoona.common.utils.JsonUtil;
import com.yoona.common.utils.JwtUtil;
import com.yoona.common.utils.WeChatUtil;
import com.yoona.system.mapper.SysUserMapper;
import com.yoona.system.dto.SysUserLoginOrRegisterDto;
import com.yoona.system.entity.SysUser;
import com.yoona.system.entity.WxSession;
import com.yoona.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Email: m15602498163@163.com
 * @Author: yoonada
 * @Date: 2020/9/21
 * @Time: 7:51 下午
 * @Msg:
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {


    private final JwtUtil jwtUtil;

    /**
     * 获取用户微信的appId
     *
     * @param code
     * @return
     * @throws Exception
     */
    @Override
    public BaseResponse<Object> getOpenId(String code) throws Exception {
        String openId = getWxAppId(code);
        return BaseResponse.success(openId);
    }

    /**
     * 微信授权登录/注册
     * @param sysUserLoginOrRegisterDto
     * @return
     */
    @Override
    public BaseResponse<Object> loginOrRegister(SysUserLoginOrRegisterDto sysUserLoginOrRegisterDto) {

        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("open_id", sysUserLoginOrRegisterDto.getOpenId());
        SysUser user = this.baseMapper.selectOne(wrapper);
        if (user == null) {
//            TODO 没注册  写注册
            SysUser sysUser = SysUser
                    .builder()
                    .openId(sysUserLoginOrRegisterDto.getOpenId())
                    .avatarUrl(sysUserLoginOrRegisterDto.getAvatarUrl())
                    .nickName(sysUserLoginOrRegisterDto.getNickName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build();
            this.baseMapper.insert(sysUser);
            return BaseResponse.success(CommonEnums.WE_CHAT_LOGIN_SUCCESS, getToken(sysUser));
        } else {
            return BaseResponse.success(CommonEnums.WE_CHAT_LOGIN_SUCCESS, getToken(user));
        }
    }

    /**
     * 微信登录
     * @param code
     * @return
     * @throws Exception
     */
    @Override
    public BaseResponse<Object> wxLogin(String code) throws Exception {
        String openId = getWxAppId(code);
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("open_id",openId);
        SysUser user = this.baseMapper.selectOne(wrapper);
        if (user == null){
            return BaseResponse.success(CommonEnums.LOGIN_NOT_AUTHORIZED_BY_WE_CHAT);
        }else {
            return BaseResponse.success(CommonEnums.WE_CHAT_LOGIN_SUCCESS, getToken(user));
        }
    }

    /**
     * 获取用户个人信息
     * @return
     */
    @Override
    public BaseResponse<Object> getUserInfo() {
        HttpServletRequest request = getHttpServletRequest();
        String uid = (String) request.getAttribute("uid");
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("uid", uid);
        SysUser sysUser = this.baseMapper.selectOne(wrapper);
        return BaseResponse.success(sysUser);
    }


    /**
     * 封装一下
     * @return
     */
    private HttpServletRequest getHttpServletRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
        return attributes.getRequest();
    }


    /**
     * 生成用户的token
     * @param user
     * @return
     */
    private String getToken(SysUser user) {
        Map<String,Object> userMap = new HashMap<>(3);
        userMap.put("uid",user.getUid());
        userMap.put("open_id",user.getOpenId());
        userMap.put("nick_name",user.getNickName());
        return jwtUtil.generateToken(userMap);
    }




    /**
     * 登录凭证校验
     * @param code
     * @return
     * @throws Exception
     */
    private String jcode2Session(String code) throws Exception {
        String sessionInfo = WeChatUtil.jsCode2Session(WeChatConstants.APP_ID, WeChatConstants.SECRET, code, "authorization_code");
        log.info(sessionInfo);
        return sessionInfo;
    }

    /**
     * 封装一下 获取微信appId
     * @param code
     * @return
     * @throws Exception
     */
    private String getWxAppId(String code) throws Exception {
        WxSession wxSession = JsonUtil.jsonToPojo(jcode2Session(code), WxSession.class);
        String openId = null;
        if (wxSession != null) {
            openId = wxSession.getOpenid();
        }
        return openId;
    }
}
